//==========================================================================
// Copyright (c) 2000-2008,  Elastos, Inc.  All Rights Reserved.
//==========================================================================
#include <elatypes.h>
#include <string.h>
#include <clsinfo.h>

_ELASTOS_NAMESPACE_USING

INLINE void RelocateUnalignedPtr(void *pPtr, size_t offset)
{
#ifdef _x86
    *(size_t *)pPtr += offset;
#else
    union
    {
        size_t  s;
        byte_t  bytes[4];
    } u;
    u.bytes[0] = ((byte_t *)pPtr)[0];
    u.bytes[1] = ((byte_t *)pPtr)[1];
    u.bytes[2] = ((byte_t *)pPtr)[2];
    u.bytes[3] = ((byte_t *)pPtr)[3];

    u.s += offset;

    ((byte_t *)pPtr)[0] = u.bytes[0];
    ((byte_t *)pPtr)[1] = u.bytes[1];
    ((byte_t *)pPtr)[2] = u.bytes[2];
    ((byte_t *)pPtr)[3] = u.bytes[3];
#endif
}

void RelocateClassInfo(CIClassInfo *pInClsInfoData,
    CIClassInfo * pClsInfo)
{
    Int32 i, j;
    CIClassEntry * pClassDir;
    CIInterfaceEntry ** ppInterfaceDir;
    CIInterfaceEntry * pInterfaceDir;
    CIMethodEntry * pMethodDir;

    memcpy(pClsInfo, pInClsInfoData, *(UInt32*)pInClsInfoData);

    pClsInfo->interfaceDir = (CIInterfaceEntry*)((Byte *)pClsInfo +
        (UInt32)pClsInfo->interfaceDir);
    pInterfaceDir = pClsInfo->interfaceDir;
    for (i = 0; i < pClsInfo->interfaceNum; i++) {
        pInterfaceDir[i].methods = (CIMethodEntry *) \
              ((Byte *)pClsInfo + (UInt32)pInterfaceDir[i].methods);
        pMethodDir = pInterfaceDir[i].methods;
        for (j = 0; j < pInterfaceDir[i].methodNumMinus3; j++) {
            pMethodDir[j].params = (CIBaseType*) \
                 ((Byte *)pClsInfo + (UInt32)pMethodDir[j].params);
        }
    }

    pClsInfo->classDir = (CIClassEntry *)((Byte *)pClsInfo +
       (UInt32)pClsInfo->classDir);
    pClassDir = pClsInfo->classDir;
    for (i = 0; i < pClsInfo->classNum; i++) {
        pClassDir[i].interfaces = (CIInterfaceEntry **) \
                ((Byte *)pClsInfo + (Int32)(pClassDir[i].interfaces));
        ppInterfaceDir = pClassDir[i].interfaces;
        for (j = 0; j < pClassDir[i].interfaceNum; j++) {
            RelocateUnalignedPtr(ppInterfaceDir + j, (size_t)pClsInfo);
        }
        pClassDir[i].pszUunm =
                (char*)((Byte *)pClsInfo + (UInt32)pClassDir[i].pszUunm);
    }
}
